package p.ithorns.integration.dynamic.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import p.ithorns.integration.dynamic.module.ModuleManagerServletRegistrar;
import p.ithorns.integration.dynamic.module.ModuleRuntimeException;
import p.ithorns.integration.dynamic.module.ScanJarPathRunner;

import java.nio.file.Paths;
import java.util.Objects;

/**
 * DynamicModuleAutoConfigurationRegistrar
 * TODO
 *
 * @author ithorns
 * @version 1.0
 * @date 2021/10/26 13:56
 */
@Slf4j
public class DynamicModuleAutoConfigurationRegistrar implements ImportBeanDefinitionRegistrar {


    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        log.info("Start to load DynamicModuleAutoConfigurationRegistrar...");

        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                metadata.getAnnotationAttributes(EnableDynamicModuleAutoConfiguration.class.getName()));
        if (Objects.isNull(attributes)) {
            throw new ModuleRuntimeException("@EnableDynamicModuleAutoConfiguration annotationAttributes is null");
        }

        String moduleJarAbsolutePath = attributes.getString("moduleJarAbsolutePath");
        // 创建目录
        boolean isNew = Paths.get(moduleJarAbsolutePath).toFile().mkdirs();
        // 注册AddServlet
        registerBeanDefinition(registry, moduleJarAbsolutePath, "newAddInstance", "addServlet");
        // 注册QueryServlet
        registerBeanDefinition(registry, moduleJarAbsolutePath, "newQueryInstance", "queryServlet");
        // 注册RemoveServlet
        registerBeanDefinition(registry, moduleJarAbsolutePath, "newRemoveInstance", "removeServlet");

        // 注册启动扫码Runner
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(ScanJarPathRunner.class)
                .addPropertyValue("moduleJarAbsolutePath", moduleJarAbsolutePath)
                .addPropertyValue("pathIsNewCreated", isNew)
                .addPropertyReference("moduleService", "moduleService")
                .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO)
                .getBeanDefinition();
        registry.registerBeanDefinition("ScanJarPathRunner", beanDefinition);
    }

    private void registerBeanDefinition(BeanDefinitionRegistry registry, String moduleJarAbsolutePath, String factoryMethod, String beanName) {
        AbstractBeanDefinition removeBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(ModuleManagerServletRegistrar.class)
                .setFactoryMethod(factoryMethod)
                .addPropertyValue("moduleJarAbsolutePath", moduleJarAbsolutePath)
                .addPropertyReference("moduleService", "moduleService")
                .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO)
                .getBeanDefinition();
        registry.registerBeanDefinition(beanName, removeBeanDefinition);
    }

}
